import type { RouteHandler } from "./handlers.ts";
import type { Method } from "./router.ts";
import type { RouteComponent } from "./segments.ts";

export interface RouteConfig {
  /**
   * A route override for the page. This is useful for pages where the route
   * can not be expressed through the filesystem routing capabilities.
   *
   * The route override must be a path-to-regexp compatible route matcher.
   */
  routeOverride?: string;

  /**
   * If Content-Security-Policy should be enabled for this page. If 'true', a
   * locked down policy will be used that allows only the scripts and styles
   * that are generated by Fresh. Additional scripts and styles can be added
   * using the `useCSP` hook.
   */
  csp?: boolean;

  /**
   * Skip already inherited layouts
   * Default: `false`
   */
  skipInheritedLayouts?: boolean;

  /**
   * Skip rendering the `routes/_app` template
   * Default: `false`
   */
  skipAppWrapper?: boolean;
  /**
   * Which method to use when loading this route lazily. This is only used
   * for lazy routes.
   * Default: `ALL`
   */
  methods?: "ALL" | Method[];
}

export interface LayoutConfig {
  /**
   * Skip already inherited layouts
   * Default: `false`
   */
  skipInheritedLayouts?: boolean;

  /**
   * Skip rendering the `routes/_app` template
   * Default: `false`
   */
  skipAppWrapper?: boolean;
}

export interface Route<State> {
  component?: RouteComponent<State>;
  config?: RouteConfig;
  handler?: RouteHandler<unknown, State>;
  /** Additional .css files to load */
  css?: string[];
}

/**
 * Lazily construct items like middlewares, handlers, etc by wrapping them
 * in a function.
 */
export type Lazy<T> = () => Promise<T>;

/**
 * Return T or lazy version of T
 */
export type MaybeLazy<T> = T | Lazy<T>;

// TODO: Uncomment once JSR supports global types
// declare global {
//   namespace preact.createElement.JSX {
//     interface HTMLAttributes {
//       /**
//        * Alternative url to fetch partials from on `<a>` or `<form>` tags
//        */
//       "f-partial"?: string | SignalLike<string>;
//       /**
//        * Enable or disable client side navigation and partials for this
//        * particular node and its children.
//        */
//       "f-client-nav"?: boolean | SignalLike<boolean>;
//     }
//   }
// }
